package de.schnocklake.android.sap.crm;

import java.util.HashMap;

import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.text.Html;
import android.view.GestureDetector;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.View.OnLongClickListener;
import android.view.inputmethod.InputMethodManager;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.AutoCompleteTextView;
import android.widget.Button;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.Spinner;
import android.widget.TableLayout;
import android.widget.TextView;
import android.widget.AdapterView.OnItemClickListener;
import de.schnocklake.android.sap.crm.datamodel.Customer;
import de.schnocklake.android.sap.crm.datamodel.Item;
import de.schnocklake.android.sap.crm.datamodel.Quotation;
import de.schnocklake.android.sap.crm.searchhelp.CRMCustomerValueHelpAdapter;
import de.schnocklake.android.sap.searchhelp.SAPValueHelpSoapAdapter;

public class CreateQuotation extends Activity {
	// holds all "business data" for the quotation
	Quotation quotation;

	private LinearLayout mainLinearLayout;
	private TableLayout itemTableLayout;
	private LayoutInflater mInflater;

	private GestureDetector gestureScanner;
	private Handler itemEditmodeToggleHandler;
	private int currentItemId;
	private String webServiceReturnMessage = "";

	private AutoCompleteTextView customerAutoCompleteTextView;
	private TextView customerDetailTextView;

	private HashMap<Integer, ItemLine> itemLines;

	/*
	 * (non-Javadoc)
	 * 
	 * @see android.app.Activity#onCreate(android.os.Bundle)
	 */
	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);

		quotation = new Quotation();

		// Horizontal Layout, where all the scrollable Screens are placed on
		mainLinearLayout = new LinearLayout(this);
		mainLinearLayout.setOrientation(LinearLayout.HORIZONTAL);
		mInflater = (LayoutInflater) this
				.getSystemService(Context.LAYOUT_INFLATER_SERVICE);

		// init screens and place them on the mainLinearLayout
		View cellscreen;
		cellscreen = initQuotationMainScreen();
		mainLinearLayout.addView(cellscreen);

		cellscreen = initQuotationItemScreen();
		mainLinearLayout.addView(cellscreen);

		cellscreen = initPricesScreen();
		mainLinearLayout.addView(cellscreen);

		// gestureScanner for handling the scrolling -- movement beteen the
		// screens
		gestureScanner = new GestureDetector(
				new GestureDetector.SimpleOnGestureListener() {
					@Override
					public boolean onScroll(MotionEvent e1, MotionEvent e2,
							float distanceX, float distanceY) {
						int newx = mainLinearLayout.getScrollX()
								+ (int) distanceX;
						if (0 <= newx && newx <= 640) {
							mainLinearLayout.scrollBy((int) distanceX, 0);
						}
						return true;
					}
				});
		setContentView(mainLinearLayout);
	}

	/**
	 * @param name
	 *            Name of the screen - Title
	 * @param leftScreenName
	 *            Name of the screen to the left
	 * @param rightScreenName
	 *            Name of the screen to the right
	 * @return
	 */
	private View createScreen(String name, String leftScreenName,
			String rightScreenName) {
		// create and init screen
		View cellscreen = mInflater.inflate(R.layout.cell, mainLinearLayout,
				false);
		cellscreen.setLayoutParams(new LinearLayout.LayoutParams(320, 480));

		// set titles for screen and right/left-navigation titles
		((TextView) cellscreen.findViewById(R.id.LeftNavigationTextView))
				.setText(leftScreenName);
		((TextView) cellscreen.findViewById(R.id.CaptionTextView))
				.setText(name);
		((TextView) cellscreen.findViewById(R.id.RightNavigationTextView))
				.setText(rightScreenName);

		return cellscreen;
	}

	private View initQuotationMainScreen() {
		// create screen
		View cellscreen = createScreen("Basic Data", "", "Items >>");

		// create content screen and place on top screen
		View quotation_main = mInflater.inflate(R.layout.quotation_main,
				mainLinearLayout, false);
		((LinearLayout) cellscreen.findViewById(R.id.ContentLinearLayout))
				.addView(quotation_main);

		// init widgets and interaction handlers

		// processingType entry field
		String[] mStrings = { "ag", "de" };
		Spinner processingTypeCodeSpinner = (Spinner) quotation_main
				.findViewById(R.id.ProcessingTypeCodeSpinner);
		ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,
				android.R.layout.simple_spinner_item, mStrings);
		adapter
				.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
		processingTypeCodeSpinner.setAdapter(adapter);

		// customer entry field and customer display field - only one of them is
		// visible at a time
		SAPValueHelpSoapAdapter autocomplete_adapter = new CRMCustomerValueHelpAdapter(
				this);
		customerDetailTextView = (TextView) quotation_main
				.findViewById(R.id.CustomerDetailTextView);
		customerDetailTextView.setVisibility(View.GONE);

		customerAutoCompleteTextView = (AutoCompleteTextView) quotation_main
				.findViewById(R.id.CustomerAutoComplete);
		customerAutoCompleteTextView.setAdapter(autocomplete_adapter);
		customerAutoCompleteTextView
				.setOnItemClickListener(new OnItemClickListener() {
					@Override
					public void onItemClick(AdapterView<?> adapterView,
							View arg1, int arg2, long arg3) {
						// customer is selected out of value help list. Change
						// the customer of the Quotation class to the selected
						quotation.setCustomer((Customer) adapterView
								.getAdapter().getItem(arg2));

						InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
						imm.hideSoftInputFromWindow(
								((EditText) customerAutoCompleteTextView)
										.getWindowToken(), 0);

						// hide edit field and show customer detail text view
						// with updated text
						customerAutoCompleteTextView.setVisibility(View.GONE);
						customerDetailTextView
								.setText(Html.fromHtml("<B>"
										+ quotation.getCustomer().getNumber()
										+ "</B> "
										+ quotation.getCustomer().getName()
										+ "<BR>"
										+ quotation.getCustomer().getCity()
										+ ", "
										+ quotation.getCustomer().getStreet()
										+ "<BR>"));
						customerDetailTextView.setVisibility(View.VISIBLE);

						// implement: if the customer detail textview is
						// longclicked, show the customer edit field to
						// enable the user to change the customer
						customerDetailTextView.setClickable(true);
						customerDetailTextView
								.setOnLongClickListener(new OnLongClickListener() {
									@Override
									public boolean onLongClick(View v) {
										customerDetailTextView
												.setVisibility(View.GONE);
										customerAutoCompleteTextView
												.setVisibility(View.VISIBLE);
										return false;
									}
								});

					}

				});

		return cellscreen;
	}

	private View initQuotationItemScreen() {
		// create screen
		View cellscreen = createScreen("Items", "<< Basic Data", "Prices >>");

		// create content screen and place on top screen
		View quotation_items = mInflater.inflate(R.layout.quotation_items,
				mainLinearLayout, false);
		((LinearLayout) cellscreen.findViewById(R.id.ContentLinearLayout))
				.addView(quotation_items);

		// init widgets and interaction handlers

		// table of items
		// each item row consists of 4 "real" layout rows. only two of them are
		// visible at a time, depending
		// on the editmode of the item.
		// editmode == true : show product edit line and detail edit line
		// editmode == false : show product display line and detail display line
		itemTableLayout = (TableLayout) quotation_items
				.findViewById(R.id.ItemsTableLayout);

		// used, when a item (in display mode) is longclicked. shows a dialog to
		// choose action for
		// this item (edit or delete)
		itemEditmodeToggleHandler = new Handler() {
			@Override
			public void handleMessage(Message msg) {
				// retrieve the id of the item that was longclicked
				currentItemId = ((ItemLine) msg.obj).getItem().getId();
				// show "choose command" dialog
				showDialog(DIALOG_ITEM_LONGCLICK);
			}
		};

		// initialize itemLine list
		itemLines = new HashMap<Integer, ItemLine>();

		// append first item to itemtable
		addItemLine();

		// init add button
		Button addItemButton = (Button) quotation_items
				.findViewById(R.id.NewRowButton);
		addItemButton.setOnClickListener(new OnClickListener() {
			@Override
			public void onClick(View v) {
				addItemLine();
			}
		});

		return cellscreen;
	}

	/**
	 * holds the Dialog used while submitting the quotation to CRM
	 */
	private ProgressDialog progressDialog;

	private View initPricesScreen() {
		// create content
		View cellscreen = createScreen("Prices", "<< Items", "");

		// create content screen and place on top screen
		View quotation_prices = mInflater.inflate(R.layout.quotation_prices,
				mainLinearLayout, false);
		((LinearLayout) cellscreen.findViewById(R.id.ContentLinearLayout))
				.addView(quotation_prices);

		// init "submit to cmr" button
		Button submitQuotationButton = (Button) quotation_prices
				.findViewById(R.id.SubmitButton);
		submitQuotationButton.setOnClickListener(new OnClickListener() {
			@Override
			public void onClick(View v) {
				// show progress dialog
				progressDialog = ProgressDialog.show(CreateQuotation.this,
						"Saving Quotation", "Please wait...", true, false);
				// start submision in background task
				new SubmitQuotationTask().execute(new String[] {});
			}
		});

		return cellscreen;
	}

	/**
	 * add new itemLine and show it as editable
	 */
	public void addItemLine() {
		// add new item ( to quotation.items and ItemLines collection ) and
		// append rows to table
		Item newItem = quotation.appendNewItem();
		itemLines.put(newItem.getId(), new ItemLine(newItem,
				CreateQuotation.this, itemTableLayout,
				itemEditmodeToggleHandler));

		// set the new item editable
		setEditableItem(newItem.getId());
	}

	/**
	 * Removes itemLine with the id = itemId
	 * 
	 * @param itemId
	 */
	public void removeItemLine(int itemId) {
		quotation.getItems().remove(itemId);
		itemLines.get(itemId).removeTableRows();
		itemLines.remove(itemId);
	}

	/**
	 * Sets itemLine with the id = itemId editable and all other lines to not
	 * editable (display)
	 * 
	 * @param itemId
	 */
	public void setEditableItem(int itemId) {
		for (ItemLine itemline : itemLines.values()) {
			itemline.setEditStatus(itemline.getItem().getId() == itemId ? true
					: false);
		}
	}

	// dialog implementations

	private static final int DIALOG_SUBMIT_RESULT = 1;
	private static final int DIALOG_ITEM_LONGCLICK = 2;

	@Override
	protected Dialog onCreateDialog(int id) {
		switch (id) {
		case DIALOG_SUBMIT_RESULT:
			// dialog to display the result of the submission
			return new AlertDialog.Builder(CreateQuotation.this).setTitle(
					"Quotaion Submission Result").setMessage(
					CreateQuotation.this.webServiceReturnMessage)
					.setPositiveButton("OK",
							new DialogInterface.OnClickListener() {
								public void onClick(DialogInterface dialog,
										int whichButton) {
									Intent intent = new Intent(
											CreateQuotation.this,
											CreateQuotation.class);
									CreateQuotation.this.startActivity(intent);
								}
							}).create();
		case DIALOG_ITEM_LONGCLICK:
			// dialog to choose the command when the user longpressed a itemLine
			return new AlertDialog.Builder(CreateQuotation.this).setItems(
					R.array.item_longclick_commands,
					new DialogInterface.OnClickListener() {
						public void onClick(DialogInterface dialog, int which) {
							String[] items = getResources().getStringArray(
									R.array.item_longclick_commands);

							if (items[which].equalsIgnoreCase("Edit Item")) {
								// set the editable lineItem
								setEditableItem(currentItemId);
							} else if (items[which]
									.equalsIgnoreCase("Remove Item")) {
								// remove lineItem
								removeItemLine(currentItemId);
							}
						}
					}).create();
		}
		return null;
	}

	private class SubmitQuotationTask extends
			AsyncTask<String, Integer, String[]> {
		protected String[] doInBackground(String... dummy) {
			// the main execution of the Background task :

			// ensure, that the datemodel and values in editfields are in sync
			for (ItemLine itemline : itemLines.values()) {
				itemline.updateValues();
			}
			// submit the quotation to CRM
			return new String[] { CreateQuotation.this.webServiceReturnMessage = CreateQuotation.this.quotation
					.createQuotation() };
		}

		protected void onProgressUpdate(Integer... progress) {
		}

		protected void onPostExecute(String[] units) {
			// called after main execution
			// dismiss "saving ..." dialog
			CreateQuotation.this.progressDialog.dismiss();
			// display submission result dialog
			CreateQuotation.this.showDialog(DIALOG_SUBMIT_RESULT);
		}
	}

	// scrolling implementation
	// used to implement the scrolling from one screen to another in conjunction
	// with gestureScanner
	@Override
	public boolean onTouchEvent(MotionEvent me) {
		boolean res = gestureScanner.onTouchEvent(me);
		if (me.getAction() == MotionEvent.ACTION_UP) {
			// is the screen 50 % of the screen width to the left, change to
			// left screen
			// is the screen 50 % of the screen width to the right, change to
			// right screen
			mainLinearLayout.scrollTo(Math.round((float) mainLinearLayout
					.getScrollX()
					/ (float) 320) * 320, 0);
		}
		return res;
	}
}